﻿using In66.Net.Repository.Entities;

namespace Whse.Api.Models.Aggregates.WarehouseAggregate
{
    /// <summary>
    /// 货架
    /// </summary>
    public class Warehouse : AggregateRoot, IConcurrency, ISoftDelete
    {
        public long? ProductId { get; private set; }

        public int Qty { get; private set; }

        public int BlockedQty { get; private set; }

        public WarehousePosition Position { get; private set; }
        /// <summary>
        /// Version
        /// </summary>
        public byte[] Version { get; set; } = Array.Empty<byte>();
        /// <summary>
        /// IsDeleted
        /// </summary>
        public bool IsDeleted { get; set; }

        public Warehouse()
        {
        }

        internal Warehouse(long id, WarehousePosition position)
        {
            this.Id = id;
            Qty = 0;
            BlockedQty = 0;
            Position = Guarder.Checker.NotNull(position, nameof(position));
        }

        /// <summary>
        /// 冻结库存
        /// </summary>
        /// <param name="needBlockedQty"></param>
        internal void BlockQty(int needBlockedQty)
        {
            if (Qty < needBlockedQty)
            {
                throw new BusinessException("Qty<needFreezedQty");
            }

            Guarder.Checker.GTZero(ProductId.Value, nameof(ProductId));

            BlockedQty += needBlockedQty;
            Qty -= needBlockedQty;
        }

        /// <summary>
        /// 移除被冻结的库存
        /// </summary>
        /// <param name="needRemoveQty"></param>
        internal void RemoveBlockedQty(int needRemoveQty)
        {
            if (BlockedQty < needRemoveQty)
            {
                throw new BusinessException("FreezedQty<needUnfreezeQty");
            }

            Guarder.Checker.GTZero(ProductId.Value, nameof(ProductId));

            BlockedQty -= needRemoveQty;
            Qty += needRemoveQty;
        }

        /// <summary>
        /// 出库
        /// </summary>
        /// <param name="qty"></param>
        internal void Deliver(int qty)
        {
            if (BlockedQty < qty)
            {
                throw new BusinessException("FreezedQty<qty");
            }

            Guarder.Checker.GTZero(ProductId.Value, nameof(ProductId));

            BlockedQty -= qty;
        }

        /// <summary>
        /// 入库
        /// </summary>
        /// <param name="qty"></param>
        internal void Entry(int qty)
        {
            Guarder.Checker.GTZero(qty, nameof(qty));
            Guarder.Checker.GTZero(ProductId.Value, nameof(ProductId));
            Qty += qty;
        }

        /// <summary>
        /// 分配货架给商品
        /// </summary>
        /// <param name="productId"></param>
        internal void SetProductId(long productId)
        {
            //if (this.ProductId.HasValue && this.ProductId == productId)
            //    throw new ArgumentException("ProductId");

            Guarder.Checker.GTZero(productId, nameof(productId));

            ProductId = productId;
        }
    }
}
